<template>
  <div class="student-management">
    <!-- Header Section -->
    <div class="header-section">
      <div class="header-content">
        <h1 class="page-title">考生管理</h1>
        <p class="page-subtitle">管理考生账号信息</p>
      </div>
      <div class="action-bar">
        <div class="search-container">
          <div class="search-input">
            <i class="icon icon-search"></i>
            <input
                type="text"
                placeholder="搜索考生..."
                v-model="searchQuery"
                @input="handleSearch"
            >
            <div class="search-suggestions" v-if="searchSuggestions.length > 0">
              <div
                  class="suggestion-item"
                  v-for="(item, index) in searchSuggestions"
                  :key="index"
                  @click="selectSuggestion(item)"
              >
                {{ item }}
              </div>
            </div>
          </div>
        </div>
        <div class="action-buttons">
          <button class="btn btn-primary" @click="showAddDialog">
            <i class="icon icon-add"></i> 添加考生
          </button>
          <button class="btn btn-secondary" @click="showImportDialog">
            <i class="icon icon-import"></i> 批量导入
          </button>
          <button
              class="btn btn-tertiary"
              v-if="selectedStudents.length > 0"
              @click="showBatchActions"
          >
            <i class="icon icon-batch"></i> 批量操作 ({{ selectedStudents.length }})
          </button>
        </div>
      </div>
    </div>

    <!-- Advanced Filters -->
    <div class="filter-section">
      <div class="filter-header" @click="toggleAdvancedFilters">
        <span>高级筛选</span>
        <i class="icon icon-chevron" :class="{ 'up': showAdvancedFilters }"></i>
      </div>
      <transition name="fade">
        <div class="filter-content" v-show="showAdvancedFilters">
          <div class="filter-row">
            <div class="filter-group">
              <label>注册时间</label>
              <div class="date-range">
                <input type="date" v-model="filterForm.registerStart">
                <span>至</span>
                <input type="date" v-model="filterForm.registerEnd">
              </div>
            </div>
            <div class="filter-group">
              <label>账号状态</label>
              <div class="status-selector">
                <label class="checkbox-label">
                  <input type="checkbox" v-model="filterForm.status" value="0"> 正常
                </label>
                <label class="checkbox-label">
                  <input type="checkbox" v-model="filterForm.status" value="1"> 禁用
                </label>
              </div>
            </div>
            <div class="filter-group">
              <label>最近活跃</label>
              <select v-model="filterForm.activity" class="filter-select">
                <option value="">全部</option>
                <option value="7">最近7天</option>
                <option value="30">最近30天</option>
                <option value="90">最近90天</option>
              </select>
            </div>
            <div class="filter-actions">
              <button class="btn btn-apply" @click="applyFilters">应用筛选</button>
              <button class="btn btn-reset" @click="resetFilters">重置</button>
            </div>
          </div>
        </div>
      </transition>
    </div>

    <!-- Data Table -->
    <div class="data-table-container">
      <div class="table-responsive">
        <div class="data-table">
          <div class="table-header">
            <div class="header-cell selection">
              <input
                  type="checkbox"
                  v-model="selectAll"
                  @change="toggleSelectAll"
              >
            </div>
            <div class="header-cell" @click="sortBy('userId')">
              ID
              <i class="sort-icon" :class="getSortClass('userId')"></i>
            </div>
            <div class="header-cell" @click="sortBy('username')">
              用户名
              <i class="sort-icon" :class="getSortClass('username')"></i>
            </div>
            <div class="header-cell" @click="sortBy('email')">
              邮箱
              <i class="sort-icon" :class="getSortClass('email')"></i>
            </div>
            <div class="header-cell" @click="sortBy('phone')">
              手机号
              <i class="sort-icon" :class="getSortClass('phone')"></i>
            </div>
            <div class="header-cell" @click="sortBy('updatedAt')">
              注册时间
              <i class="sort-icon" :class="getSortClass('updatedAt')"></i>
            </div>
            <div class="header-cell" @click="sortBy('status')">
              状态
              <i class="sort-icon" :class="getSortClass('status')"></i>
            </div>
            <div class="header-cell actions">
              操作
            </div>
          </div>

          <div class="table-body">
            <div v-if="loading" class="loading-row">
              <div class="loading-spinner"></div>
              <span>加载中...</span>
            </div>
            <div v-else-if="filteredStudents.length === 0" class="empty-row">
              <i class="icon icon-empty"></i>
              <span>没有找到符合条件的考生</span>
              <button class="btn btn-primary" @click="resetFilters">重置筛选条件</button>
            </div>
            <template v-else>
              <div
                  class="table-row"
                  v-for="student in paginatedStudents"
                  :key="student.userId"
                  :class="{ 'selected': isSelected(student) }"
              >
                <div class="table-cell selection">
                  <input
                      type="checkbox"
                      :value="student.userId"
                      v-model="selectedStudents"
                  >
                </div>
                <div class="table-cell">{{ student.userId }}</div>
                <div class="table-cell user-cell">
                  <div class="user-avatar" :style="{ backgroundColor: getAvatarColor(student.userId) }">
<!--                    {{ getInitials(student.realName || student.username) }}-->
                    {{ getInitials(student.realName || student.username) }}
                  </div>
                  <div class="user-info">
                    <div class="username">{{ student.username }}</div>
                    <div class="real-name">{{ student.realName || '未设置' }}</div>
                  </div>
                </div>
                <div class="table-cell">{{ student.email || '-' }}</div>
                <div class="table-cell">{{ student.phone || '-' }}</div>
                <div class="table-cell">
                  <span class="date-with-tooltip" :title="formatFullDate(student.updatedAt)">
                    {{ formatDate(student.updatedAt) }}
                  </span>
                </div>
                <div class="table-cell">
                  <span class="status-badge" :class="student.status === 0 ? 'active' : 'inactive'">
                    {{ student.status === 0 ? '正常' : '禁用' }}
                  </span>
                </div>
                <div class="table-cell actions">
                  <button
                      class="btn-action"
                      @click="editStudent(student)"
                      title="编辑"
                  >
                    <i class="icon icon-edit"></i>
                  </button>
                  <button
                      class="btn-action"
                      @click="toggleStatus(student)"
                      :title="student.status === 0 ? '禁用账号' : '启用账号'"
                  >
                    <i class="icon icon-status" :class="student.status === 0 ? 'disable' : 'enable'"></i>
                  </button>
                  <button
                      class="btn-action"
                      @click="resetPassword(student)"
                      title="重置密码"
                  >
                    <i class="icon icon-reset"></i>
                  </button>
                  <button
                      class="btn-action"
                      @click="showDetail(student)"
                      title="查看详情"
                  >
                    <i class="icon icon-detail"></i>
                  </button>
                </div>
              </div>
            </template>
          </div>
        </div>
      </div>

      <!-- Pagination -->
      <div class="pagination-wrapper" v-if="filteredStudents.length > 0">
        <!-- 修改分页信息显示部分 -->
        <div class="pagination-info">
          显示 {{ (currentPage - 1) * pageSize + 1 }}-{{ Math.min(currentPage * pageSize, filteredStudents.length) }} 条，
          共 {{ filteredStudents.length }} 条
        </div>

        <!-- 修改分页按钮部分 -->
        <div class="pagination-controls">
          <button
              class="pagination-btn"
              :disabled="currentPage === 1"
              @click="currentPage = 1"
          >
            首页
          </button>
          <button
              class="pagination-btn"
              :disabled="currentPage === 1"
              @click="currentPage--"
          >
            上一页
          </button>

          <button
              v-for="page in visiblePages"
              :key="page"
              class="pagination-btn"
              :class="{ 'active': page === currentPage }"
              @click="currentPage = page"
          >
            {{ page }}
          </button>

          <button
              class="pagination-btn"
              :disabled="currentPage >= totalPages"
              @click="currentPage++"
          >
            下一页
          </button>
          <button
              class="pagination-btn"
              :disabled="currentPage >= totalPages"
              @click="currentPage = totalPages"
          >
            末页
          </button>

          <select v-model="pageSize" class="page-size-select" @change="handlePageSizeChange">
            <option value="10">10条/页</option>
            <option value="20">20条/页</option>
            <option value="50">50条/页</option>
            <option value="100">100条/页</option>
          </select>
        </div>
      </div>
    </div>

    <!-- Modals -->
    <transition name="modal">
      <div class="modal-mask" v-if="showAddEditModal">
        <div class="modal-wrapper">
          <div class="modal-container">
            <div class="modal-header">
              <h3>{{ isEditing ? '编辑考生信息' : '添加新考生' }}</h3>
              <button class="modal-close" @click="closeAddEditModal">
                <i class="icon icon-close"></i>
              </button>
            </div>
            <div class="modal-body">
              <form class="student-form" @submit.prevent="handleStudentSubmit">
                <div class="form-group">
                  <label>用户名</label>
                  <input
                      type="text"
                      v-model="currentStudent.username"
                      required
                      placeholder="输入用户名"
                  >
                </div>
                <div class="form-group">
                  <label>真实姓名</label>
                  <input
                      type="text"
                      v-model="currentStudent.realName"
                      placeholder="输入真实姓名"
                  >
                </div>
                <div class="form-group">
                  <label>邮箱</label>
                  <input
                      type="email"
                      v-model="currentStudent.email"
                      placeholder="输入邮箱"
                  >
                </div>
                <div class="form-group">
                  <label>手机号</label>
                  <input
                      type="tel"
                      v-model="currentStudent.phone"
                      placeholder="输入手机号"
                  >
                </div>
                <div class="form-group">
                  <label>初始密码</label>
                  <input
                      type="password"
                      v-model="currentStudent.password"
                      :required="!isEditing"
                      placeholder="输入密码"
                  >
                </div>
                <div class="form-group">
                  <label>状态</label>
                  <div class="radio-group">
                    <label>
                      <input
                          type="radio"
                          v-model="currentStudent.status"
                          :value="0"
                      > 正常
                    </label>
                    <label>
                      <input
                          type="radio"
                          v-model="currentStudent.status"
                          :value="1"
                      > 禁用
                    </label>
                  </div>
                </div>
                <div class="form-actions">
                  <button type="button" class="btn btn-secondary" @click="closeAddEditModal">
                    取消
                  </button>
                  <button type="submit" class="btn btn-primary">
                    {{ isEditing ? '更新' : '添加' }}
                  </button>
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>
    </transition>

    <transition name="modal">
      <div class="modal-mask" v-if="showImportModal">
        <div class="modal-wrapper">
          <div class="modal-container">
            <div class="modal-header">
              <h3>批量导入考生</h3>
              <button class="modal-close" @click="closeImportModal">
                <i class="icon icon-close"></i>
              </button>
            </div>
            <div class="modal-body">
              <div class="import-instructions">
                <p>1. 下载导入模板文件</p>
                <p>2. 按照模板格式填写考生信息</p>
                <p>3. 上传填写好的文件</p>
              </div>
              <div class="import-actions">
                <button class="btn btn-secondary" @click="downloadTemplate">
                  <i class="icon icon-download"></i> 下载模板
                </button>
                <div class="file-upload">
                  <input
                      type="file"
                      id="importFile"
                      accept=".xlsx,.xls,.csv"
                      @change="handleFileUpload"
                  >
                  <label for="importFile" class="btn btn-primary">
                    <i class="icon icon-upload"></i> 选择文件
                  </label>
                  <span class="file-name">{{ importFileName || '未选择文件' }}</span>
                </div>
              </div>
              <div class="import-progress" v-if="importProgress > 0">
                <div class="progress-bar" :style="{ width: importProgress + '%' }"></div>
                <span>{{ importProgress }}%</span>
              </div>
            </div>
            <div class="modal-footer">
              <button class="btn btn-secondary" @click="closeImportModal">
                取消
              </button>
              <button
                  class="btn btn-primary"
                  :disabled="!importFile"
                  @click="confirmImport"
              >
                开始导入
              </button>
            </div>
          </div>
        </div>
      </div>
    </transition>

    <transition name="modal">
      <div class="modal-mask" v-if="showBatchModal">
        <div class="modal-wrapper">
          <div class="modal-container">
            <div class="modal-header">
              <h3>批量操作 ({{ selectedStudents.length }}个考生)</h3>
              <button class="modal-close" @click="closeBatchModal">
                <i class="icon icon-close"></i>
              </button>
            </div>
            <div class="modal-body">
              <div class="batch-options">
                <div class="batch-option">
                  <label>操作类型</label>
                  <select v-model="batchOperationType" class="batch-select">
                    <option value="enable">启用账号</option>
                    <option value="disable">禁用账号</option>
                    <option value="reset">重置密码</option>
                    <option value="delete">删除账号</option>
                  </select>
                </div>
                <div class="batch-option" v-if="batchAction === 'reset'">
                  <label>新密码</label>
                  <input
                      type="password"
                      v-model="batchPassword"
                      placeholder="输入新密码"
                  >
                </div>
              </div>
            </div>
            <div class="modal-footer">
              <button class="btn btn-secondary" @click="closeBatchModal">
                取消
              </button>
              <button class="btn btn-primary" @click="confirmBatchAction">
                确认执行
              </button>
            </div>
          </div>
        </div>
      </div>
    </transition>
  </div>
</template>

<script>
import { mapState, mapGetters, mapActions } from 'vuex'

export default {
  name: 'StudentManagement',
  data() {
    return {
      // 搜索相关状态
      searchQuery: '',

      // 筛选相关状态
      showAdvancedFilters: false,
      filterForm: {
        registerStart: '',  // 注册开始日期
        registerEnd: '',    // 注册结束日期
        status: [],        // 账号状态筛选
        activity: ''       // 最近活跃天数
      },

      // 分页相关状态
      currentPage: 1,      // 当前页码
      pageSize: 10,        // 每页显示数量

      // 模态框相关状态
      showAddEditModal: false,  // 添加/编辑对话框显示状态
      showImportModal: false,   // 导入对话框显示状态
      showBatchModal: false,    // 批量操作对话框显示状态
      isEditing: false,         // 当前是否为编辑模式

      // 当前操作的学生数据
      currentStudent: {
        username: '',    // 用户名
        realName: '',   // 真实姓名
        email: '',       // 邮箱
        phone: '',       // 手机号
        password: '',    // 密码
        status: 0        // 账号状态 (0-正常,1-禁用)
      },

      // 批量选择相关状态
      selectedStudents: [],  // 已选学生ID数组
      selectAll: false,      // 全选状态

      // 导入相关状态
      importFile: null,      // 导入文件对象
      importFileName: '',     // 导入文件名
      importProgress: 0,     // 导入进度

      // 批量操作相关状态
      batchOperationType: 'enable',  // 批量操作类型 (enable/disable/reset/delete)
      batchPassword: ''       // 批量重置密码时的新密码
    }
  },
  computed: {
    // 映射Vuex状态
    ...mapState('user', [
      'loading',  // 加载状态
      'error'     // 错误信息
    ]),

    // 映射Vuex getters
    ...mapGetters('user', [
      'filteredExaminees',    // 过滤后的考生列表
      'paginatedExaminess',   // 分页后的考生数据
      'totalPages',           // 总页数
      'visiblePages',         // 可见页码范围
      'searchSuggestions',    // 搜索建议
      'rawTotalPages',        // 原始总页数(未过滤)
      'rawPaginatedExaminees' // 原始分页数据(未过滤)
    ]),

    // 兼容性计算属性 - 保持模板不变
    filteredStudents() {
      return this.filteredExaminees || []
    },
    paginatedStudents() {
      return this.rawPaginatedExaminees || []
    }
  },
  watch: {
    // 每页大小变化时重置到第一页并更新数据
    pageSize() {
      this.currentPage = 1
      this.updatePagination()
      this.fetchExaminees()
    },

    // 搜索词变化时更新Vuex状态
    searchQuery(newVal) {
      this.$store.commit('user/SET_SEARCH_QUERY', newVal)
    },

    // 已选学生变化时更新"全选"状态
    selectedStudents(newVal) {
      this.selectAll = newVal.length === this.filteredStudents.length && this.filteredStudents.length > 0
    },

    // 当前页码变化时更新Vuex状态并重新获取数据
    currentPage(newVal) {
      // 确保页码在合理范围内
      if (newVal < 1) {
        this.currentPage = 1
        return
      }

      // 只有当totalPages > 0 时才检查上限
      if (this.totalPages > 0 && newVal > this.totalPages) {
        this.currentPage = this.totalPages
        return
      }

      // 更新Vuex中的分页状态
      this.updatePagination()

      // 调用fetchExaminees获取数据
      this.fetchExaminees()
    },

    pageSize() {
      this.currentPage = 1
      this.updatePagination()
      this.fetchExaminees()
    }
  },
  created() {
    // 组件创建时获取考生数据
    this.fetchExaminees()
  },
  methods: {
    // 映射Vuex actions
    ...mapActions('user', {
      fetchExaminees: 'fetchExaminees',
      updateExaminee: 'updateExaminee',
      deleteExaminee: 'deleteExaminee',
      addExaminee: 'addExaminee',
      updateExamineeStatus: 'updateExamineeStatus',
      resetPassword: 'resetPassword',
      doBatchAction: 'batchAction'  // 使用别名避免冲突
    }),

    handlePageSizeChange() {
      this.currentPage = 1
      this.updatePagination()
      this.fetchExaminees()
    },

    updatePagination() {
      this.$store.commit('user/SET_PAGINATION', {
        currentPage: this.currentPage,
        pageSize: this.pageSize
      })
    },

    /**
     * 处理搜索输入
     */
    handleSearch() {
      this.currentPage = 1
      this.fetchExaminees() // 触发重新获取数据
    },

    /**
     * 切换全选状态
     */
    toggleSelectAll() {
      if (this.selectAll) {
        // 选中所有当前页的学生
        this.selectedStudents = this.paginatedStudents.map(student => student.userId)
      } else {
        this.selectedStudents = []
      }
    },

    /**
     * 检查学生是否被选中
     * @param {Object} student - 学生对象
     * @returns {Boolean} 是否选中
     */
    isSelected(student) {
      return this.selectedStudents.includes(student.userId)
    },

    /**
     * 按字段排序
     * @param {String} field - 要排序的字段名
     */
    sortBy(field) {
      // 获取当前排序状态
      const currentSort = this.$store.state.user.sort

      // 确定新的排序顺序
      const order = currentSort.field === field
          ? currentSort.order === 'asc' ? 'desc' : 'asc'
          : 'asc'

      // 提交排序变更到Vuex
      this.$store.commit('user/SET_SORT', { field, order })

      // 重新获取数据
      this.fetchExaminees()
    },

    /**
     * 获取排序图标的类名
     * @param {String} field - 字段名
     * @returns {String} 图标类名
     */
    getSortClass(field) {
      const sort = this.$store.state.user.sort
      if (sort.field !== field) return ''
      return sort.order === 'asc' ? 'asc' : 'desc'
    },

    // 切换高级筛选的显示/隐藏
    toggleAdvancedFilters() {
      this.showAdvancedFilters = !this.showAdvancedFilters
    },

    // 应用筛选条件
    applyFilters() {
      // 更新Vuex中的筛选条件
      this.$store.commit('user/SET_FILTERS', this.filterForm)
      this.currentPage = 1
      this.fetchExaminees()
      this.showSuccess('筛选条件已应用')
    },

    // 重置筛选条件
    resetFilters() {
      this.filterForm = {
        registerStart: '',
        registerEnd: '',
        status: [],
        activity: ''
      }
      this.searchQuery = ''
      this.currentPage = 1
      // 重置Vuex中的筛选条件
      this.$store.commit('user/RESET_FILTERS')
      this.fetchExaminees()
      this.showSuccess('筛选条件已重置')
    },

    // 更新分页信息到Vuex
    updatePagination() {
      this.$store.commit('user/SET_PAGINATION', {
        currentPage: this.currentPage,
        pageSize: this.pageSize
      })
    },

    // 显示添加学生对话框
    showAddDialog() {
      this.isEditing = false
      this.currentStudent = {
        username: '',
        realName: '',
        email: '',
        phone: '',
        password: '',
        status: 0
      }
      this.showAddEditModal = true
    },

    // 显示编辑学生对话框
    editStudent(student) {
      this.isEditing = true
      this.currentStudent = { ...student }
      this.showAddEditModal = true
    },

    // 关闭添加/编辑对话框
    closeAddEditModal() {
      this.showAddEditModal = false
    },

    // 处理学生表单提交
    async handleStudentSubmit() {
      try {
        if (this.isEditing) {
          // 调用更新学生的action
          await this.updateExaminee(this.currentStudent)
          this.showSuccess('考生信息更新成功')
        } else {
          await this.addExaminee(this.currentStudent)
          this.showSuccess('考生添加成功')
        }
        this.showAddEditModal = false
        await this.fetchExaminees()
      } catch (error) {
        // console.error('保存考生信息失败:', error)
        this.showError('保存考生信息失败')
      }
    },

    // 显示导入对话框
    showImportDialog() {
      this.importFile = null
      this.importFileName = ''
      this.importProgress = 0
      this.showImportModal = true
    },

    // 关闭导入对话框
    closeImportModal() {
      this.showImportModal = false
    },

    // 显示批量操作对话框
    showBatchActions() {
      this.batchActionData = 'enable'
      this.batchPassword = ''
      this.showBatchModal = true
    },

    // 关闭批量操作对话框
    closeBatchModal() {
      this.showBatchModal = false
    },

    /**
     * 切换学生状态
     * @param {Object} student - 学生对象
     */
    async toggleStatus(student) {
      try {
        const newStatus = student.status === 0 ? 1 : 0
        await this.updateExamineeStatus({
          ids: [student.userId],
          status: newStatus
        })
        this.showSuccess(`账号已${newStatus === 0 ? '启用' : '禁用'}`)
      } catch (error) {
        // console.error('更改状态失败:', error)
        this.showError('更改状态失败')
      }
    },

    /**
     * 重置密码
     * @param {Object} student - 学生对象
     */
    async resetPassword(student) {
      try {
        // 提示用户输入新密码
        const newPassword = prompt('请输入新密码:')
        if (!newPassword) return

        await this.resetPassword({
          userId: student.userId,
          password: newPassword
        })
        this.showSuccess(`考生 ${student.username} 的密码已重置`)
      } catch (error) {
        // console.error('重置密码失败:', error)
        this.showError('重置密码失败')
      }
    },

    /**
     * 确认批量操作
     */
    async confirmBatchAction() {
      try {
        await this.doBatchAction({
          action: this.batchOperationType,
          ids: this.selectedStudents,
          password: this.batchPassword
        })

        let message = ''
        const selectedCount = this.selectedStudents.length

        switch (this.batchOperationType) {
          case 'enable':
            message = `已启用 ${selectedCount} 个账号`
            break
          case 'disable':
            message = `已禁用 ${selectedCount} 个账号`
            break
          case 'reset':
            message = `已重置 ${selectedCount} 个账号的密码`
            break
          case 'delete':
            message = `已删除 ${selectedCount} 个账号`
            break
        }

        this.selectedStudents = []
        this.closeBatchModal()
        this.showSuccess(message)
        await this.fetchExaminees() // 刷新数据
      } catch (error) {
        console.error('批量操作失败:', error)
        this.showError('批量操作失败')
      }
    },

    /* ========== 辅助方法 ========== */

    /**
     * 生成基于姓名的唯一3位数字标识码
     * @param {String} name - 姓名
     * @returns {String} 3位数字代码
     */
    getInitials(name = '') {
      // 使用闭包保持持久状态
      if (!this._initialsState) {
        this._initialsState = {
          counter: 0,
          usedCodes: new Set(),
          lastTimestamp: 0
        };
      }
      const state = this._initialsState;

      let attempts = 0;
      let code;

      do {
        // 1. 基础哈希生成
        let hash = 5381;
        const input = name || '';
        for (let i = 0; i < input.length; i++) {
          hash = (hash * 33) ^ input.charCodeAt(i);
        }

        // 2. 动态因子混合
        const timestamp = Date.now();
        const dynamicFactors = [
          hash,
          state.counter++,
          timestamp ^ (timestamp >> 16),
          state.lastTimestamp = timestamp
        ];

        // 3. 生成3位候选码
        const mixedValue = dynamicFactors.reduce((val, factor) =>
            (val * 31 + factor) % 1000, 0);
        code = String(mixedValue).padStart(3, '0');

        // 4. 冲突解决
        if (attempts++ > 50) {
          code = String((parseInt(code) + attempts * 101) % 1000)
              .padStart(3, '0');
        }

        if (attempts > 100) {
          throw new Error('无法生成唯一编码');
        }

      } while (state.usedCodes.has(code));

      // 记录已使用编码
      state.usedCodes.add(code);
      if (state.usedCodes.size > 999) {
        state.usedCodes = new Set([code]);
      }

      return code;
    },

    /**
     * 根据ID获取头像背景色
     * @param {Number} id - 学生ID
     * @returns {String} 颜色代码
     */
    getAvatarColor(id) {
      const colors = [
        '#FF6B6B', '#4ECDC4', '#45B7D1', '#A37BBA',
        '#FFA07A', '#98D8C8', '#F06292', '#7986CB'
      ]
      return colors[id % colors.length]
    },

    /**
     * 格式化日期为本地日期字符串
     * @param {String} dateString - ISO日期字符串
     * @returns {String} 格式化后的日期
     */
    formatDate(dateString) {
      const date = new Date(dateString)
      return date.toLocaleDateString('zh-CN')
    },

    /**
     * 格式化日期为完整的本地日期时间字符串
     * @param {String} dateString - ISO日期字符串
     * @returns {String} 格式化后的日期时间
     */
    formatFullDate(dateString) {
      const date = new Date(dateString)
      return date.toLocaleString('zh-CN')
    },

    /**
     * 显示成功通知
     * @param {String} message - 通知消息
     */
    showSuccess(message) {
      const notification = document.createElement('div')
      notification.className = 'notification success'
      notification.innerHTML = `<i class="icon icon-check"></i> ${message}`
      document.body.appendChild(notification)

      setTimeout(() => {
        notification.classList.add('fade-out')
        setTimeout(() => {
          document.body.removeChild(notification)
        }, 300)
      }, 3000)
    },

    /**
     * 显示错误通知
     * @param {String} message - 通知消息
     */
    showError(message) {
      const notification = document.createElement('div')
      notification.className = 'notification error'
      notification.innerHTML = `<i class="icon icon-error"></i> ${message}`
      document.body.appendChild(notification)

      setTimeout(() => {
        notification.classList.add('fade-out')
        setTimeout(() => {
          document.body.removeChild(notification)
        }, 300)
      }, 3000)
    },

    /**
     * 显示信息通知
     * @param {String} message - 通知消息
     */
    showInfo(message) {
      const notification = document.createElement('div')
      notification.className = 'notification info'
      notification.innerHTML = `<i class="icon icon-info"></i> ${message}`
      document.body.appendChild(notification)

      setTimeout(() => {
        notification.classList.add('fade-out')
        setTimeout(() => {
          document.body.removeChild(notification)
        }, 300)
      }, 3000)
    }
  }
}
</script>

<style lang="less" scoped>
@import "@/styles/variables.less";


/* Color Variables */
@primary: #4361ee;
@primary-light: rgba(@primary, 0.1);
@primary-dark: darken(@primary, 10%);
@secondary: #3f37c9;
@success: #4cc9f0;
@danger: #f72585;
@warning: #f8961e;
@info: #4895ef;
@light: #f8f9fa;
@dark: #212529;
@gray-50: #f9fafb;
@gray-100: #f8f9fa;
@gray-200: #e9ecef;
@gray-300: #dee2e6;
@gray-400: #ced4da;
@gray-500: #adb5bd;
@gray-600: #6c757d;
@gray-700: #495057;
@gray-800: #343a40;
@gray-900: #212529;

/* Base Styles */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}

body {
font-family: 'Segoe UI', 'PingFang SC', -apple-system, BlinkMacSystemFont, sans-serif;
color: @gray-800;
background-color: @gray-100;
line-height: 1.6;
}

.student-management {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
background-color: white;
overflow: hidden;
}

/* Header Section */
.header-section {
  padding: 16px 24px 0;
  margin-bottom: 0;
  background-color: white;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  z-index: 10;
  .header-content {
    // 面板标题样式
    .panel-title {
      margin: 0;
      font-size: 1.75rem;
      font-weight: 700;
      color: @gray-900;
      position: relative;
      padding-left: 1rem;

      // 标题左侧的渐变线条
      &::before {
        content: '';
        position: absolute;
        left: 0;
        top: 0;
        bottom: 0;
        width: 4px;
        background: linear-gradient(to bottom, @primary, @secondary);
        border-radius: 2px;
      }
    }

    // 面板副标题样式
    .panel-subtitle {
      margin: 0.5rem 0 0;
      font-size: 0.9375rem;
      color: @gray-500;
    }
  }
}



.action-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    margin-bottom: 16px;
  }

/* Search Container */
.search-container {
flex: 1;
min-width: 200px;
position: relative;

.search-input {
position: relative;

.icon-search {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: @gray-500;
z-index: 1;
}

input {
width: 100%;
padding: 10px 12px 10px 36px;
border: 1px solid @gray-300;
border-radius: 6px;
font-size: 14px;
background-color: @gray-100;
transition: all 0.2s ease;

&:focus {
outline: none;
border-color: @primary;
background-color: white;
box-shadow: 0 0 0 3px rgba(@primary, 0.1);
}

&::placeholder {
color: @gray-500;
}
}
}

.search-suggestions {
position: absolute;
top: 100%;
left: 0;
right: 0;
background-color: white;
border: 1px solid @gray-200;
border-radius: 0 0 6px 6px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
z-index: 10;
max-height: 200px;
overflow-y: auto;

.suggestion-item {
padding: 8px 16px;
cursor: pointer;
transition: background-color 0.2s;

&:hover {
background-color: @gray-100;
}
}
}
}

/* Button Styles */
.btn {
padding: 10px 16px;
border-radius: 6px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 6px;
transition: all 0.2s;
border: none;
white-space: nowrap;

&:disabled {
opacity: 0.6;
cursor: not-allowed;
}

&.btn-primary {
background: @primary;
color: white;

&:hover:not(:disabled) {
background: @primary-dark;
}
}

&.btn-secondary {
background: white;
color: @primary;
border: 1px solid @primary;

&:hover:not(:disabled) {
background: @gray-100;
}
}

&.btn-tertiary {
background: @gray-100;
color: @gray-800;
border: 1px solid @gray-300;

&:hover:not(:disabled) {
background: @gray-200;
}
}

&.btn-apply {
background: @primary;
color: white;
}

&.btn-reset {
background: white;
color: @gray-700;
border: 1px solid @gray-300;
}
}

/* Filter Section */
.filter-section {
margin: 10px 24px 16px;
border: 1px solid @gray-200;
border-radius: 6px;
background: white;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);

.filter-header {
padding: 12px 16px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
font-size: 14px;
font-weight: 500;
color: @gray-700;

&:hover {
background: @gray-50;
}
}

.filter-content {
padding: 16px;
border-top: 1px solid @gray-100;

.filter-row {
display: flex;
gap: 24px;
flex-wrap: wrap;
}

.filter-group {
flex: 1;
min-width: 200px;

label {
display: block;
margin-bottom: 8px;
font-size: 13px;
color: @gray-700;
font-weight: 500;
}

input[type="date"] {
width: 100%;
padding: 8px 12px;
border: 1px solid @gray-300;
border-radius: 4px;
font-size: 14px;
transition: all 0.2s;

&:focus {
outline: none;
border-color: @primary;
box-shadow: 0 0 0 3px rgba(@primary, 0.1);
}
}

.date-range {
display: flex;
align-items: center;
gap: 8px;

span {
color: @gray-500;
}
}

.status-selector {
display: flex;
gap: 16px;
padding-top: 6px;

label {
display: flex;
align-items: center;
gap: 6px;
margin-bottom: 0;
cursor: pointer;
font-weight: normal;
}
}

.filter-select {
width: 100%;
padding: 8px 12px;
border: 1px solid @gray-300;
border-radius: 4px;
font-size: 14px;
background-color: white;
transition: all 0.2s;

&:focus {
outline: none;
border-color: @primary;
box-shadow: 0 0 0 3px rgba(@primary, 0.1);
}
}
}

.filter-actions {
display: flex;
gap: 8px;
margin-top: 24px;
width: 100%;
}
}
}

/* Data Table Container */
.data-table-container {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
margin: 0 24px 24px;
}

/* Table Responsive */
.table-responsive {
flex: 1;
overflow: auto;
border: 1px solid @gray-200;
border-radius: 6px;
background: white;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

/* Data Table */
.data-table {
width: 100%;
min-width: 1000px;

.table-header {
display: grid;
grid-template-columns: 50px 80px 1fr 1fr 1fr 1fr 100px 120px;
background: @gray-50;
font-size: 14px;
font-weight: 600;
color: @gray-700;
position: sticky;
top: 0;
z-index: 1;

.header-cell {
padding: 12px 16px;
display: flex;
align-items: center;
gap: 6px;
cursor: pointer;
user-select: none;
transition: background-color 0.2s;

&:hover {
background: @gray-100;
}

&.selection {
justify-content: center;
}

&.actions {
justify-content: center;
}
}
}

.table-body {
.loading-row,
.empty-row {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 0;
color: @gray-500;
grid-column: 1 / -1;
}

.loading-spinner {
width: 32px;
height: 32px;
border: 4px solid @gray-200;
border-top-color: @primary;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 16px;
}

.empty-row {
i {
font-size: 40px;
opacity: 0.5;
margin-bottom: 16px;
}

button {
margin-top: 16px;
}
}

.table-row {
display: grid;
grid-template-columns: 50px 80px 1fr 1fr 1fr 1fr 100px 120px;
border-bottom: 1px solid @gray-100;
transition: all 0.2s;

&:last-child {
border-bottom: none;
}

&:hover {
background: @gray-50;
}

&.selected {
background-color: @primary-light;
}

.table-cell {
padding: 12px 16px;
font-size: 14px;
display: flex;
align-items: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

&.selection {
justify-content: center;
}

&.user-cell {
display: flex;
align-items: center;
gap: 12px;

.user-avatar {
width: 36px;
height: 36px;
border-radius: 50%;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: 500;
font-size: 14px;
flex-shrink: 0;
}

.user-info {
overflow: hidden;

.username {
font-weight: 500;
margin-bottom: 2px;
overflow: hidden;
text-overflow: ellipsis;
}

.real-name {
font-size: 13px;
color: @gray-500;
overflow: hidden;
text-overflow: ellipsis;
}
}
}

.date-with-tooltip {
cursor: default;
}

.status-badge {
padding: 4px 10px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
display: inline-block;
min-width: 50px;
text-align: center;

&.active {
background: rgba(@success, 0.1);
color: darken(@success, 20%);
}

&.inactive {
background: rgba(@danger, 0.1);
color: darken(@danger, 10%);
}
}

&.actions {
justify-content: center;
gap: 8px;

.btn-action {
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: none;
border: none;
cursor: pointer;
color: @gray-600;
transition: all 0.2s;

&:hover {
background: @gray-100;
color: @gray-800;
}
}
}
}
}
}
}

/* Pagination */
.pagination-wrapper {
padding: 16px 0;
margin-top: 16px;
background: white;
border-top: 1px solid @gray-200;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 16px;
height: 150px;

.pagination-info {
font-size: 14px;
color: @gray-600;
}

.pagination-controls {
display: flex;
align-items: center;
gap: 8px;
}

.pagination-btn {
padding: 8px 12px;
border: 1px solid @gray-300;
background-color: white;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
min-width: 36px;

&:hover:not(:disabled) {
background-color: @gray-100;
}

&:disabled {
opacity: 0.6;
cursor: not-allowed;
}

&.active {
background-color: @primary;
color: white;
border-color: @primary;
}
}

.page-size-select {
padding: 8px 12px;
border: 1px solid @gray-300;
border-radius: 4px;
font-size: 14px;
margin-left: 8px;
}
}

/* Modal Styles */
.modal-mask {
position: fixed;
z-index: 100;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
transition: opacity 0.3s ease;
}

.modal-wrapper {
max-width: 90%;
width: 100%;
max-height: 90vh;
overflow-y: auto;
}

.modal-container {
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
transition: all 0.3s ease;
width: 100%;
max-width: 600px;
margin: 0 auto;
overflow: hidden;
}

.modal-header {
padding: 16px 24px;
border-bottom: 1px solid @gray-200;
display: flex;
justify-content: space-between;
align-items: center;

h3 {
margin: 0;
font-size: 18px;
font-weight: 600;
color: @gray-800;
}
}

.modal-close {
background: none;
border: none;
cursor: pointer;
color: @gray-500;
font-size: 20px;
transition: color 0.2s;

&:hover {
color: @gray-700;
}
}

.modal-body {
padding: 24px;
max-height: 70vh;
overflow-y: auto;
}

.modal-footer {
padding: 16px 24px;
border-top: 1px solid @gray-200;
display: flex;
justify-content: flex-end;
gap: 12px;
}

/* Form Styles */
.student-form {
.form-group {
margin-bottom: 16px;

label {
display: block;
margin-bottom: 8px;
font-size: 14px;
font-weight: 500;
color: @gray-700;
}

input {
width: 100%;
padding: 10px 12px;
border: 1px solid @gray-300;
border-radius: 4px;
font-size: 14px;
transition: all 0.2s;

&:focus {
outline: none;
border-color: @primary;
box-shadow: 0 0 0 3px rgba(@primary, 0.1);
}
}

.radio-group {
display: flex;
gap: 16px;
margin-top: 8px;

label {
display: flex;
align-items: center;
gap: 8px;
font-weight: normal;
cursor: pointer;
}
}
}

.form-actions {
display: flex;
justify-content: flex-end;
gap: 12px;
margin-top: 24px;
}
}

/* Import Modal Styles */
.import-instructions {
margin-bottom: 24px;

p {
margin-bottom: 8px;
color: @gray-700;
}
}

.import-actions {
display: flex;
flex-direction: column;
gap: 16px;
margin-bottom: 24px;
}

.file-upload {
display: flex;
align-items: center;
gap: 12px;

input[type="file"] {
display: none;
}

.file-name {
font-size: 14px;
color: @gray-600;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}

.import-progress {
margin-top: 16px;
height: 8px;
background-color: @gray-200;
border-radius: 4px;
overflow: hidden;
position: relative;

.progress-bar {
height: 100%;
background-color: @primary;
transition: width 0.3s ease;
}

span {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
font-size: 12px;
color: white;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
}
}

/* Batch Modal Styles */
.batch-options {
.batch-option {
margin-bottom: 16px;

label {
display: block;
margin-bottom: 8px;
font-size: 14px;
font-weight: 500;
color: @gray-700;
}

.batch-select {
width: 100%;
padding: 10px 12px;
border: 1px solid @gray-300;
border-radius: 4px;
font-size: 14px;
}

input {
width: 100%;
padding: 10px 12px;
border: 1px solid @gray-300;
border-radius: 4px;
font-size: 14px;
}
}
}

/* Icon Styles */
.icon {
display: inline-block;
width: 16px;
height: 16px;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
vertical-align: middle;
}

.icon-search {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z' /%3E%3C/svg%3E");
}

.icon-add {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M12 6v6m0 0v6m0-6h6m-6 0H6' /%3E%3C/svg%3E");
}

.icon-import {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12' /%3E%3C/svg%3E");
}

.icon-edit {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z' /%3E%3C/svg%3E");
}

.icon-status {
&.enable {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 13l4 4L19 7' /%3E%3C/svg%3E");
}

&.disable {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M6 18L18 6M6 6l12 12' /%3E%3C/svg%3E");
}
}

.icon-reset {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15' /%3E%3C/svg%3E");
}

.icon-detail {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z' /%3E%3C/svg%3E");
}

.icon-chevron {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7' /%3E%3C/svg%3E");

&.up {
transform: rotate(180deg);
}
}

.icon-empty {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M20 12H4' /%3E%3C/svg%3E");
}

.icon-close {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M6 18L18 6M6 6l12 12' /%3E%3C/svg%3E");
}

.icon-download {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4' /%3E%3C/svg%3E");
}

.icon-upload {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12' /%3E%3C/svg%3E");
}

.icon-batch {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10' /%3E%3C/svg%3E");
}

.icon-check {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 13l4 4L19 7' /%3E%3C/svg%3E");
}

.icon-error {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z' /%3E%3C/svg%3E");
}

.icon-info {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z' /%3E%3C/svg%3E");
}

/* Sort Icon */
.sort-icon {
width: 12px;
height: 12px;
opacity: 0.5;
display: inline-block;
background-size: contain;
background-repeat: no-repeat;
background-position: center;

&.asc {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 15l7-7 7 7' /%3E%3C/svg%3E");
opacity: 1;
}

&.desc {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7' /%3E%3C/svg%3E");
opacity: 1;
}
}

/* Notification Styles */
.notification {
position: fixed;
bottom: 20px;
right: 20px;
padding: 12px 16px;
border-radius: 6px;
color: white;
display: flex;
align-items: center;
gap: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
z-index: 1000;
transition: all 0.3s ease;

&.success {
background-color: @success;
}

&.error {
background-color: @danger;
}

&.info {
background-color: @info;
}

&.fade-out {
opacity: 0;
transform: translateY(20px);
}
}

/* Animations */
@keyframes spin {
to { transform: rotate(360deg); }
}

.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}

.modal-enter {
opacity: 0;
}

.modal-leave-active {
opacity: 0;
}

.modal-enter .modal-container,
.modal-leave-active .modal-container {
transform: scale(1.1);
}

/* Responsive Design */
@media (max-width: 992px) {
.data-table {
.table-header,
.table-row {
grid-template-columns: 50px 80px 1fr 1fr 1fr 120px;

.header-cell:nth-child(4),
.table-cell:nth-child(4) {
display: none;
}
}
}
}

@media (max-width: 768px) {
.header-section {
padding: 12px 16px 0;
}

.filter-section {
margin: 0 16px 16px;

.filter-row {
flex-direction: column;
gap: 16px;
}
}

.data-table-container {
margin: 0 16px 16px;
}

.data-table {
.table-header,
.table-row {
grid-template-columns: 50px 80px 1fr 1fr 100px;

.header-cell:nth-child(5),
.table-cell:nth-child(5) {
display: none;
}
}
}

.pagination-wrapper {
flex-direction: column;
align-items: stretch;
gap: 12px;
}
}

@media (max-width: 576px) {
.header-section {
.action-bar {
flex-direction: column;
gap: 12px;

.search-container {
width: 100%;
}
}
}

.data-table {
.table-header,
.table-row {
grid-template-columns: 50px 1fr 80px;

.header-cell:nth-child(3),
.header-cell:nth-child(6),
.table-cell:nth-child(3),
.table-cell:nth-child(6) {
display: none;
}
}
}

.modal-wrapper {
max-width: 95%;
}
}

/* ========== 标题样式（优化为题库管理风格） ========== */
.header-section {
  padding: 20px 24px 16px;
  background-color: white;
  border-bottom: 1px solid @gray-200;

  .header-content {
    margin-bottom: 16px;

    .page-title {
      font-size: 20px;
      font-weight: 600;
      color: @gray-900;
      margin: 0;
      position: relative;
      padding-left: 12px;

      &::before {
        content: '';
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        height: 16px;
        width: 4px;
        background: linear-gradient(to bottom, @primary, @secondary);
        border-radius: 2px;
      }
    }

    .page-subtitle {
      font-size: 14px;
      color: @gray-500;
      margin: 8px 0 0;
      line-height: 1.5;
    }
  }
}

/* ========== 搜索框样式（统一为题库管理风格） ========== */
.action-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 16px;

  .search-container {
    flex: 1;
    max-width: 400px;

    .search-input {
      position: relative;

      i {
        position: absolute;
        left: 12px;
        top: 50%;
        transform: translateY(-50%);
        color: @gray-400;
        font-size: 16px;
      }

      input {
        width: 100%;
        padding: 10px 16px 10px 40px;
        border: 1px solid @gray-200;
        border-radius: 6px;
        font-size: 14px;
        color: @gray-700;
        background-color: white;
        transition: all 0.2s ease;
        box-shadow: @shadow-sm;

        &::placeholder {
          color: @gray-400;
        }

        &:focus {
          outline: none;
          border-color: @primary;
          box-shadow: 0 0 0 2px @primary-lighter;
        }
      }
    }

    .search-suggestions {
      position: absolute;
      top: 100%;
      left: 0;
      right: 0;
      background: white;
      border: 1px solid @gray-200;
      border-top: none;
      border-radius: 0 0 6px 6px;
      box-shadow: @shadow-md;
      z-index: 10;
      max-height: 200px;
      overflow-y: auto;

      .suggestion-item {
        padding: 8px 16px;
        font-size: 14px;
        color: @gray-700;
        cursor: pointer;
        transition: background-color 0.2s;

        &:hover {
          background-color: @gray-50;
        }
      }
    }
  }

  /* ========== 按钮样式 ========== */
  .action-buttons {
    display: flex;
    align-items: center;
    gap: 12px;

    .btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: 10px 16px;
      border-radius: 6px;
      font-size: 14px;
      font-weight: 500;
      cursor: pointer;
      transition: all 0.2s ease;
      border: none;
      gap: 6px;
      white-space: nowrap;

      &-primary {
        background: @primary;
        color: white;
        box-shadow: @shadow-sm;

        &:hover {
          background: darken(@primary, 8%);
        }

        &:active {
          background: darken(@primary, 12%);
        }
      }

      &-secondary {
        background: white;
        color: @primary;
        border: 1px solid @gray-200;
        box-shadow: @shadow-sm;

        &:hover {
          background: @gray-50;
          border-color: @gray-300;
        }
      }
    }
  }
}

/* ========== 响应式设计 ========== */
@media (max-width: 768px) {
  .header-section {
    padding: 16px;

    .action-bar {
      flex-direction: column;
      align-items: stretch;
      gap: 12px;

      .search-container {
        max-width: 100%;
      }

      .action-buttons {
        justify-content: flex-end;
      }
    }
  }
}
</style>